﻿using Newtonsoft.Json;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.DataLayer.ConnectionStrings;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Entities;
using Sustainalytics.Entities.ConnectionStrings;
using Sustainalytics.Entities.ESGRatings;
using Sustainalytics.EsgRatings.BusinessLogic;
using Sustainalytics.ESGRatings.Tasks.HttpClients;
using Sustainalytics.LongRunningTaskManager;
using Sustainalytics.LongRunningTaskManager.Interface;
using System;
using System.Configuration;

namespace Sustainalytics.ESGRatings.Tasks
{

    public class EsgReportDownloadTask : ILongRunningTask
    {
        private readonly string _clientDWConnectionString;

        public EsgReportDownloadTask()
        {
            var clientPlatformConnectionString = ConfigurationManager.ConnectionStrings["ClientPlatform"].ConnectionString;

            var connectionStringsManager =
                ConnectionStringsManager.GetInstance(
                    ConnectionStringsRepository.GetInstance(clientPlatformConnectionString));

            connectionStringsManager.GetConnectionString(ConnectionStringType.CompanyReportPDF);
            _clientDWConnectionString = connectionStringsManager.GetConnectionString(ConnectionStringType.ClientDW);
        }

        public LongRunningTaskTypeEnum Type
        {
            get { return LongRunningTaskTypeEnum.ESGCompanyReportPDF; }
        }

        public object Start(LongRunningTaskContext context)
        {
            var uri = new Uri(string.Format("{0}/api/v1", ConfigurationManager.AppSettings["ESGRatingServiceUrl"]));

            CompanyReportSerilog.Log.TryUrl(uri.ToString());

            var parameters = GetReportParameters(context.ParamJson, this._clientDWConnectionString);

            return TryGenerateReport(context, uri, parameters);
        }

        private EsgCompanyReportParameters GetReportParameters(string esgReportParams, string clientDWConnectionString)
        {
            var parameters = JsonConvert.DeserializeObject<EsgCompanyReportParameters>(esgReportParams);

            var company = new RepositoryCollection<CorporateData>(clientDWConnectionString).Read(parameters.CompanyId);

            if (company.ResearchParentId.HasValue)
            {
                parameters.CompanyId = company.ResearchParentId.Value;
            }

            parameters.HasComprehensiveResearch = company.ComprehensiveEsgResearchState.ResearchState == BusinessResearchProductStates.Entities.ResearchState.ResearchState.ResearchAvailable;

            parameters.FileName = GetFileName(parameters, company);
            return parameters;
        }

        private string GetFileName(EsgCompanyReportParameters parameters, CorporateData company)
        {
            var reportName = parameters.IsSummaryReport ? ReportName.ESGSummary : ReportName.ESGRatings;
            return reportName.GetFullReportName(company.CompanyName, parameters.CompanyId);
        }

        private LongRunningTaskS3FileResult TryGenerateReport(
            LongRunningTaskContext context,
            Uri uri,
            EsgCompanyReportParameters parameters)
        {
            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }

            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            using (var client = new ESGCompanyReportClient(uri, parameters, context.Ticket))
            {
                var executionResult = client.PostAsync().Result;

                if (executionResult.IsSuccessStatusCode)
                {
                    var result = client.GetResponseMessageAsync(executionResult).Result;
                    if (result != null)
                    {
                        return new LongRunningTaskS3FileResult
                        {
                            MimeType = "application/pdf",
                            Bucket = result.S3Bucket,
                            FileName = result.FileName,
                            Key = result.S3Key
                        };
                    }

                    context.SetErrorToContext(
                        6001,
                        "Failed to generate the ESG Company Report for specified parameters");
                    return null;
                }

                var error = client.GetErrorMessageAsync(executionResult).Result;

                if (error != null)
                {
                    context.SetErrorToContext(error.ErrorCode, error.ErrorMessage);
                }
            }

            return null;
        }
    }
}
